package com.fubowen.reader.book.impl

import com.fubowen.reader.extension.toNumber
import com.fubowen.reader.extension.fetchOrThrow
import com.fubowen.reader.extension.trimChar
import org.jsoup.nodes.Element
import java.net.URL

object WebBookGetter {

    fun getChapterList(url: String): List<Chapter> {
        var document = fetchOrThrow(url)
        var aList = document.select("a[href]").toList()
        var chapterNodeList = aList.getChapterNodeList()
        if (chapterNodeList.isEmpty()) {
            val catalogUrl = aList.getCatalogUrl()
            check(catalogUrl.isNotEmpty()) { "没有获得书籍目录" }
            for (it in catalogUrl) {
                document = fetchOrThrow(it)
            }
        }
        aList = document.select("a[href]").toList()
        chapterNodeList = aList.getChapterNodeList()
        check(chapterNodeList.isNotEmpty()) { "没有获得章节列表" }
        return chapterNodeList.toChapter()
    }

    fun getChapterText(url: String): String {
        val document = fetchOrThrow(url)
        val node = document.selectFirst(":has(>br:gt(10))")
        return node?.wholeText()?.replace("\r", "\n") ?: ""
    }

    private fun List<Element>.getChapterNodeList(): List<Element> {
        var regex = Regex("第\\s*[一二三四五六七八九十零\\d]+\\s*章(.*)$")
        var data = this.filter { regex.containsMatchIn(it.text()) }
        if (data.isEmpty()) {
            regex = Regex("(\\p{IsHan}+)（[一二三四五六七八九十零\\d]+）")
            data = this.filter { regex.containsMatchIn(it.text()) }
        }
        return data
    }

    private fun List<Element>.toChapter(): List<Chapter> {
        val chapterList = mutableListOf<Chapter>()
        val regex = Regex("第\\s*([一二三四五六七八九十零\\d]+)\\s*章(.*)$")
        for (item in this) {
            val matchResult = regex.find(item.text())
            val href = item.attr("href")
            val url = URL(URL(item.baseUri()), href).toExternalForm()
            if (matchResult != null) {
                val bean = Chapter(
                    name = matchResult.groupValues[2].trimChar() ?: "",
                    nameRaw = item.text(),
                    order = matchResult.groupValues[1].toNumber(),
                    orderRaw = matchResult.groupValues[1],
                    url = url
                )
                chapterList.add(bean)
            }
        }
        return chapterList
    }

    private fun List<Element>.getCatalogUrl(): List<String> {
        val regex = Regex("目录|章节列表|返回目录|在线阅读")
        return this.filter { regex.matches(it.text()) }.map { URL(URL(it.baseUri()), it.attr("href")).toExternalForm() }
    }

    data class Chapter(var name: String = "", var nameRaw: String = "", var url: String = "", val order: Int = 0, val orderRaw: String = "")
}